home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / dcg301up / object.scr < prev    next >
Encoding:
Text File  |  1993-05-24  |  38.4 KB  |  1,174 lines

  1. !
  2. ! Default script OBJECT.SCR.
  3. !
  4. ! This is the default script for handling objects.  It is invoked whenever
  5. ! an object is manipulated (Talk, Get, Drop, Wear, Remove, Look, Examine,
  6. ! Invoke, Use and Exit) under the following conditions:
  7. !
  8. ! a) If the object has a script assigned to it, that script is invoked
  9. !    first.
  10. ! b) If the object's script terminates with CONTINUE, or if the object
  11. !    does not have a script, then this script is invoked.
  12. !
  13. ! You may modify this script at will, but one thing to remember is that
  14. ! this script should NEVER terminate with CONTINUE.  The reason is that
  15. ! objects may explicitly state that their script is 'OBJECT', in which
  16. ! case a 'CONTINUE' would execute this script twice! (Once as the script
  17. ! assigned to the object, and another time because the script ended with
  18. ! continue).
  19. !
  20. ! (c) DC Software, 1992
  21. !
  22.  
  23. !------------------------------------------------------------------------!
  24. :@TALK ! Talk to the object !
  25. !------------------------------------------------------------------------!
  26.   if npc.count then
  27.     writeln( "The ", npc.type, " has nothing to say.." );
  28.   else
  29.     writeln( "How do you talk to an ", object.type, "?" );
  30.   endif;
  31.   STOP;
  32.  
  33. !------------------------------------------------------------------------!
  34. :@GET ! Get the object (pick it up) !
  35. !------------------------------------------------------------------------!
  36.   if npc.count then writeln( "You can't do that.." ); STOP; endif;
  37.   if object.endgame = END_ON_GET then  ! Game ends on a GET of this object !
  38.     if object.endtext > 0 then         ! .. this text is displayed first.. !
  39.       readtext( object.endtext );
  40.     endif;                             ! .. then the game ends. !
  41.     ENDGAME;
  42.   endif;
  43.   if object.type = CHEST and object.locktype then ! Locked !
  44.     writeln( "You must first UNLOCK the chest, then GET the gold!" );
  45.   elsif object.type = CHEST or object.type = GOLDSACK then
  46.     if object.value = 0 then
  47.       L(1) = object.count * player.hp * 10 + random( 100 ) + 1;
  48.     else
  49.       L(1) = object.value * object.count;
  50.       if L(1) <= 0 then
  51.         L(1) = object.value;
  52.       endif;
  53.     endif;
  54.     writeln( "Got ", $L1, " (gold pieces)."  );
  55.     group.gold = group.gold + L(1);
  56.     vanish( object );
  57.   elsif object.type = FOOD and object.class = 0 then
  58.     writeln( "Got ", object.count, " units of food." );
  59.     group.food = group.food + object.count;
  60.     vanish( object );
  61.   elsif object.weight = 999 then
  62.     writeln( "The ", object.name, " is much too heavy." );
  63.   elsif object.weight = 998 then
  64.     writeln( "The ", object.name, " is can't be moved." );
  65.   elsif object.weight = 997 then
  66.     writeln( "Why would you want to take the ", object.name, "?" );
  67.   elsif object.weight > 255 then
  68.     writeln( "You can't move it!" );
  69.   elsif object.weight > player.mload then
  70.     writeln( "You are not strong enough to carry it!" );
  71.   elsif object.weight > 1 and object.weight + player.load > player.mload then
  72.     writeln( "Your load is too heavy!" );
  73.   else
  74.     L(0) = object.count;
  75.     move( object, player.bp );  ! OBJECT does not exist after MOVE !
  76.     if success then
  77.       writeln("Got ", L(0), " ", player.bp.name );
  78.     elsif object.count = L(0) then
  79.       writeln("You couldn't carry it");
  80.     else
  81.       writeln("You could only carry ", L(0) - object.count, " of them." );
  82.     endif;
  83.   endif;
  84.   STOP;
  85.  
  86. !------------------------------------------------------------------------!
  87. :@DROP      ! Drop the object on the floor !
  88. !------------------------------------------------------------------------!
  89.   if curritem.count > 1 then
  90.     L(0) = getnum( "How many? ", 0, curritem.count );
  91.     if L(0) > 0 then 
  92.       writeln( "You drop ", L(0), " ", curritem.name, "(s)" );
  93.       drop( curritem, L(0) );  
  94.     endif;
  95.   else
  96.     writeln( "You drop the ", curritem.name );
  97.     drop( curritem );
  98.   endif;
  99.   STOP;
  100.  
  101. !------------------------------------------------------------------------!
  102. :@WEAR      ! Wear or Wield the object !
  103. !------------------------------------------------------------------------!
  104.   L(0) = 0;  ! Hands needed to hold the item..
  105.  
  106.   on curritem.type goto
  107.    WR_FOOD,     WR_WEAPON,     WR_AMMO,      WR_ARMOR,      WR_SHIELD,
  108.    WR_AMULET,   WR_RING,       WR_POTION,    WR_SCROLL,     WR_STAFF;
  109. !
  110. ! the rest can't be worn, so no need to list them..
  111. !  WR_CHEST,    WR_KEYS,       WR_GEMS,      WR_BOOK,       WR_GOLDSACK,
  112. !  WR_TORCH,    WR_LANTERN,    WR_ROPE,      WR_HOOKS,      WR_MIRROR,
  113. !  WR_SIGN,     WR_VEHICLE
  114. !
  115.  
  116. :WR_FOOD
  117. :WR_AMMO
  118. :WR_POTION
  119. :WR_SCROLL
  120.    writeln( "How do you wear a ", curritem.type, "? " );
  121.    STOP;
  122.  
  123. :WR_WEAPON
  124.    if (player.class = ELF or player.class = WIZARD or player.class = ARCHER) 
  125.       and curritem.weight > 5 + adjustments(player.str) then
  126.      writeln( "This weapon is too heavy for this character class." );
  127.    elsif player.class = WIZARD and curritem.hands > 1 then
  128.      writeln( "Wizards can only use one-handed weapons" );
  129.    elsif (player.class = WIZARD or player.class = DWARF) and curritem.class = MISSILE then
  130.      writeln( "Wizards and dwarfs can't use non-magical missile weapons" );
  131.    elsif player.weapon.count > 0 then
  132.      writeln( "You must first remove the ", player.weapon.name );
  133.    else
  134.      L(0) = curritem.hands; ! Hands needed to hold the weapon !
  135.      S0 = "wielding";
  136.      goto WR_DOIT;
  137.    endif;
  138.    STOP;
  139.  
  140. :WR_ARMOR
  141.    if (player.class = ELF or player.class = WIZARD) and
  142.       curritem.weight > 5 + adjustments(player.str) then
  143.      writeln( "This armor is too heavy for an elf or a wizard" );
  144.    elsif player.class = ARCHER and
  145.       curritem.weight > 10 + adjustments(player.str) then
  146.      writeln( "This armor is too cumbersome for an archer" );
  147.    elsif player.armor.count > 0 then
  148.      writeln( "You must first remove the ", player.armor.name );
  149.    else
  150.      S0 = "wearing";
  151.      goto WR_DOIT;
  152.    endif;
  153.    STOP;
  154.  
  155. :WR_SHIELD
  156.    if player.class = WIZARD or player.class = ARCHER or player.class = DWARF then
  157.      writeln( player.class, "s cannot use a shield!" );
  158.    elsif player.class = ELF and curritem.weight > 5 + adjustments(player.str) then
  159.      writeln( "The shield is too heavy for an ELF." );
  160.    elsif player.shield.count > 0 then
  161.      writeln( "You must first remove the ", player.shield.name );
  162.    else
  163.      L(0) = 1;             ! A shield always needs 1 hand.. !
  164.      S0 = "using";
  165.      goto WR_DOIT;
  166.    endif;
  167.    STOP;
  168.  
  169. :WR_STAFF
  170.    L(0) = 1;             ! A staff always needs 1 hand.. !
  171.    if player.class = FIGHTER then
  172.      writeln( "Fighters can't use magic staffs." );
  173.    elsif curritem.charges = 0 then
  174.      writeln( "The staff has no charges left.." );
  175.    elsif player.staff.count > 0 then
  176.      writeln( "You must first remove the ", player.staff.name );
  177.    else
  178.      S0 = "holding";
  179.      goto WR_DOIT;
  180.    endif;
  181.    STOP;
  182.  
  183. :WR_AMULET
  184. :WR_RING
  185.    if player.class = FIGHTER then
  186.      writeln( "Fighters can't use magic ", curritem.type, "s." );
  187.    elsif curritem.charges = 0 then
  188.      writeln( "The ", curritem.type, " has no charges left.." );
  189.    elsif curritem.type = AMULET and player.amulet.count > 0 then
  190.      writeln( "You must first remove the ", player.amulet.name );
  191.    elsif curritem.type = RING and player.ring.count > 0 then
  192.      writeln( "You must first remove the ", player.ring.name );
  193.    else
  194.      S0 = "wearing";
  195.      goto WR_DOIT;
  196.    endif;
  197.    STOP;
  198.  
  199. :WR_DOIT
  200.   L(1) = 2; ! Player has 2 hands.. !
  201.   if player.weapon.count then dec( L(1), player.weapon.hands ); endif;
  202.   if player.shield.count then dec( L(1), 1 );                   endif;
  203.   if player.staff.count  then dec( L(1), 1 );                   endif;
  204.   if L(0) > L(1) then
  205.     writeln( "You don't have enough free hands!" );
  206.     STOP;
  207.   endif;
  208.   !
  209.   move( curritem, player.body, 1 );
  210.   if success then
  211.     writeln( "You are now ", s0, " the ", player.body.name );
  212.     if player.body.type = ARMOR or player.body.type = SHIELD then
  213.       if player.armor.cursed or player.shield.cursed then
  214.         player.ac = 0;
  215.       else
  216.         inc(player.ac,player.body.ac);
  217.       endif;
  218.     elsif player.body.type = RING or player.body.type = AMULET then
  219.       if( player.body.charges > 0 ) then
  220.         curritem = player.body;
  221.         gosub M1_INVOKE;
  222.         if curritem.charges < 255 then
  223.           dec( curritem.charges );
  224.         endif;
  225.       else
  226.         writeln( "The ", player.body.type, " has no charges." );
  227.       endif;
  228.     endif;
  229.   endif;
  230.   STOP;
  231.  
  232. !------------------------------------------------------------------------!
  233. :@REMOVE    ! Remove an object !
  234. !------------------------------------------------------------------------!
  235.   if curritem.cursed then
  236.     writeln( "The ", curritem.type, " is cursed and cannot be removed.." );
  237.     STOP;
  238.   endif;
  239.   move( curritem, player.bp, 1 );
  240.   if success then
  241.     writeln( "You remove the ", player.bp.name );
  242.   endif;
  243.   STOP;
  244.  
  245. !------------------------------------------------------------------------!
  246. :@LOOK      ! Look at an object                                          !
  247. !------------------------------------------------------------------------!
  248.   L(255) = FALSE;   ! Do not give DETAILED description !
  249.   gosub DESCRIBE;
  250.   STOP;
  251.  
  252. !------------------------------------------------------------------------!
  253. :@EXAMINE   ! Examine the object in detail                               !
  254. !------------------------------------------------------------------------!
  255.   L(255) = TRUE;   ! Give DETAILED description !
  256.   gosub DESCRIBE;
  257.   STOP;
  258.  
  259. !------------------------------------------------------------------------!
  260. :@INVOKE  ! Invoke an object we are carrying..
  261. !------------------------------------------------------------------------!
  262. !
  263. ! Called when an object we are carrying in the backpack or that we are
  264. ! wearing has a magical effect that needs to be executed.  The effect
  265. ! may be of type 1 (food,potion,ring,amulet,gem) or type 2 (scroll,staff).
  266. !
  267.   if curritem.endgame = END_ON_USE then
  268.     if curritem.endtext > 0 then         ! .. this text is displayed first.. !
  269.       readtext( curritem.endtext );
  270.     endif;                             ! .. then the game ends. !
  271.     ENDGAME;
  272.   endif;
  273.   if curritem.type = FOOD or curritem.type = POTION then
  274.     player.energy = 255;     ! Not hungry any more.. 
  275.     gosub M1_INVOKE;
  276.     if curritem.type = POTION and curritem.count > 1 then
  277.       curritem.name = curritem.class;
  278.     endif;
  279.     dec( curritem.count );
  280.   elsif curritem.type = SCROLL or curritem.type = STAFF then
  281.     gosub M2_INVOKE;
  282.   elsif curritem.type = GEMS or curritem.type = RING or curritem.type = AMULET then
  283.     gosub M1_INVOKE;
  284.     if curritem.charges < 255 then
  285.       dec( curritem.charges );
  286.       if curritem.count > 1 then
  287.         curritem.name = curritem.class;
  288.       endif;
  289.       if curritem.type = GEMS and curritem.charges = 0 then
  290.         writeln( "The ", curritem.type, " vanishes after you use it." );
  291.         dec( curritem.count );
  292.       endif;
  293.     endif;
  294.   else
  295.     writeln( "The ", curritem.name, " has no magical properties.." );  
  296.   endif;
  297.   STOP;
  298.  
  299. !------------------------------------------------------------------------!
  300. :@USE ! Use an object laying on the ground before us..
  301. !------------------------------------------------------------------------!
  302. !
  303. ! Called when an object that is laying on the ground is 'used'.  Note that
  304. ! 'use' means different things for different object types, and that in 
  305. ! order to invoke an item you have 'get' it and sometimes 'wear' it.
  306. !
  307.   if object.endgame = END_ON_USE then
  308.     if object.endtext > 0 then         ! .. this text is displayed first.. !
  309.       readtext( object.endtext );
  310.     endif;                             ! .. then the game ends. !
  311.     ENDGAME;
  312.   endif;
  313.  
  314.   on object.type goto
  315.    USE_FOOD,     USE_WEAPON,     USE_AMMO,      USE_ARMOR,      USE_SHIELD,
  316.    USE_AMULET,   USE_RING,       USE_POTION,    USE_SCROLL,     USE_STAFF,
  317.    USE_CHEST,    USE_KEYS,       USE_GEMS,      USE_BOOK,       USE_GOLDSACK,
  318.    USE_TORCH,    USE_LANTERN,    USE_ROPE,      USE_HOOKS,      USE_MIRROR,
  319.    USE_SIGN,     USE_VEHICLE;
  320.  
  321.   writeln( "I don't know how to do that with the ", object.name );
  322.   STOP;
  323.  
  324.   :USE_FOOD
  325.   :USE_POTION
  326.      if object.class then
  327.        writeln( "You must 'get' it, then 'quaff' (eat) it.." );
  328.      else
  329.        writeln( "Just 'get' it.." );
  330.      endif;
  331.      STOP;
  332.  
  333.   :USE_GEMS
  334.   :USE_SCROLL
  335.      writeln( "You must first 'get' it, then 'invoke' it.." );
  336.      STOP;
  337.  
  338.   :USE_AMULET
  339.   :USE_RING
  340.   :USE_ARMOR
  341.   :USE_WEAPON
  342.   :USE_SHIELD
  343.   :USE_STAFF
  344.      writeln( "You must first 'get' it, then 'wear' or 'wield' it.." );
  345.      STOP;
  346.  
  347.   :USE_AMMO
  348.      writeln( "Just carry it in your backpack.  If you 'wield' a " );
  349.      writeln( "weapon that uses this type of ammo, it will get used" );
  350.      writeln( "automaticly." );
  351.      STOP;
  352.  
  353.   :USE_CHEST
  354.      ! Unlock the chest !
  355.      if object.locktype then
  356.        L(0) = 0;
  357.        :UCLOOP
  358.           setbp( player, L(0) );
  359.           if player.bp.type = KEYS and player.bp.keytype = object.locktype then
  360.             writeln( object.name, " unlocked.." );
  361.             object.locktype = 0;
  362.             STOP;
  363.           endif;
  364.           inc( L(0) );
  365.           if L(0) < 16 goto :UCLOOP;
  366.        writeln( "You don't have the right key!  Break the lock?" );
  367.        if getstr( "Yes", "No" ) = 0 then
  368.          if random( 2 + adjustments(player.str) ) > 0 then
  369.            write( "You broke the lock!" );
  370.            if object.traptype = 1 then
  371.              voice( "Argh", 1000 ); ! 1000 = DCSOUNDS.VFL !
  372.              writeln( "Argh.. Poison trap!" );
  373.              player.poisoned = 1;
  374.            elsif object.traptype > 1 then
  375.              voice( "Explode", 1000 ); ! Play standard sound effect !
  376.              writeln( "Bomb Trap!" );
  377.              dec( player.hp, object.damage );
  378.              if player.hp = 0 then
  379.                writeln( player.name, " has died.." );
  380.              endif;
  381.            endif;
  382.            object.locktype = 0;
  383.          else
  384.            writeln( "It doesn't break!" );
  385.          endif;
  386.        else
  387.           writeln( "Ok." );
  388.        endif;
  389.      else
  390.        writeln( "It is not locked.." );
  391.      endif;
  392.      STOP;
  393.  
  394.   :USE_KEYS
  395.      writeln( "Just 'Get' it and carry it in case you find a lock that" );
  396.      writeln( "the key can open!" );
  397.      STOP;
  398.  
  399.   :USE_BOOK
  400.      writeln( "To read it, just 'Look' at it.." );
  401.      STOP;
  402.  
  403.   :USE_GOLDSACK
  404.      L(1) = getnum("How many gold pieces do you want to put in it?",
  405.                          0, group.gold / 10) * 10;
  406.      if L(1) then
  407.        writeln( "You put ", $L1, " in the bag." );
  408.        inc( object.value, L(1) );
  409.        dec( group.gold, L(1) );
  410.      else
  411.        writeln( "Smart move.." );
  412.      endif;
  413.      STOP;
  414.  
  415.   :USE_TORCH
  416.   :USE_LANTERN
  417.      writeln( "Save your torches.. I haven't implemented LIGHT yet!" );
  418.      STOP;
  419.  
  420.   :USE_ROPE
  421.      writeln( "After fooling around with it for a while, you manage to" );
  422.      writeln( "get yourself tangled up..." );
  423.      STOP;
  424.  
  425.   :USE_HOOKS
  426.      voice( "Ouch", 1000 );
  427.      writeln( "Ouch! (it's sharp!)" );
  428.      STOP;
  429.  
  430.   :USE_MIRROR
  431.      writeln( "Yes, you are ugly, but that doesn't matter here.." );
  432.      STOP;
  433.  
  434.   :USE_SIGN
  435.      writeln( "It's not yours.  You can 'Read' it if you wish.." );
  436.      STOP;
  437.  
  438.   :USE_VEHICLE
  439.      if group.vehicle.count then
  440.        writeln( "You must first exit the one you are in!" );
  441.        STOP;
  442.      endif;
  443.      if object.x <> group.x and object.y <> group.y then
  444.        writeln( "You must be standing next to the ", object.name );
  445.      else
  446.        group.x = object.x;            ! Move over to it !
  447.        group.y = object.y;            
  448.        move( object, group.vehicle, 1 ); ! Now board the object !
  449.        if success then
  450.          writeln( "You are on riding the ", group.vehicle.name );
  451.        endif;
  452.      endif;
  453.      STOP;
  454.  
  455. !------------------------------------------------------------------------!
  456. :@EXIT ! Exit a VEHICLE (since this is an object we are talking about..)
  457. !------------------------------------------------------------------------!
  458.   if curritem.count = 0 then
  459.     writeln("You are already on foot!" );
  460.     STOP;
  461.   endif;
  462.   if curritem.type <> VEHICLE then
  463.     writeln("BUG: CURRITEM in :@EXIT in OBJECT.SCR is not a vehicle!" );
  464.   endif;
  465.   if group.vehicle.count = 0 then
  466.     writeln("BUG: CURRITEM is not GROUP.VEHICLE on @EXIT in OBJECT.SCR" );
  467.   endif;
  468.   drop( group.vehicle );
  469.   voice( "Exit", 1000 );
  470.   writeln( "You are now on foot.." );
  471.   STOP;
  472.  
  473. !------------------------------------------------------------------------!
  474. !--  SCRIPT SUBROUTINES ARE GROUPED HERE AT THE END.  THIS IS A CHOICE --!
  475. !--  NOT A REQUIREMENT.  IT MAKES THE MAIN SCRIPT CODE ABOVE A LITTLE  --!
  476. !--  BIT EASIER TO FOLLOW.  ---------------------------------------------!
  477. !------------------------------------------------------------------------!
  478.  
  479. !------------------------------------------------------------------------!
  480. !
  481. ! SUBROUTINE: DESCRIBE
  482. !
  483. ! This routine is invoked from @LOOK, @EXAMINE and by the ANALYZE spell
  484. ! to describe a given item.
  485. !
  486. !------------------------------------------------------------------------!
  487. :DESCRIBE
  488. !------------------------------------------------------------------------!
  489.  
  490. ! First, handle the case where you are looking at a CHARACTER
  491.  
  492.   if npc.count then
  493.     if npc.picture >= 0 then
  494.       viewpcx( npc );
  495.       if success then
  496.         pause;
  497.       endif;
  498.       paint( screen );
  499.     endif;
  500.     write( "Name: ", npc.name, ", Type: ", npc.type );
  501.     if npc.type = HOSTILE and npc.weapon.count then
  502.       write( ", Weapon: ", npc.weapon.name, ", Damage: ", npc.weapon.damage, ", Range: ", npc.weapon.range );
  503.     endif;
  504.     if L(255) then
  505.       write( ", Class: ", npc.class, ", Lvl: ", npc.level, ", AC: ", npc.ac, ", HP: ", npc.hp );
  506.     endif;
  507.     writeln(".");
  508.     STOP;
  509.   endif;
  510.   if object.picture >= 0 then
  511.     viewpcx( object );
  512.     if success then
  513.       pause;
  514.     endif;
  515.     paint( screen );
  516.   elsif object.type = SIGN or object.type = BOOK then
  517.     readtext( object.text );
  518.     STOP;
  519.   endif;
  520.   write( "You see a ", object.name );
  521.   if NOT L(255) then
  522.     writeln;
  523.     STOP;
  524.   endif;
  525.   write( ", Type: ", object.type );
  526. !
  527. ! The following is a 'cascading if..then..elsif..elsif.....else..endif' 
  528. ! statement.  It is used here to illustrate it's usefulness.  The same
  529. ! code could have been written with a 'ON object.type GOTO' statement.
  530. !
  531.   if object.type = FOOD or object.type = POTION  then
  532.     if object.class then
  533.       write( ", Class: ", object.class );
  534.       if object.class <> CURE then
  535.         write( ", Units: ", object.units );
  536.       endif;
  537.     endif;
  538.   elsif object.type = WEAPON then
  539.     write( ", Class: ", object.class, 
  540.            ", Hands: ", object.hands, 
  541.            ", Range: ", object.range, 
  542.            ", Damage: ", object.damage );
  543.     if object.ammoneeded then
  544.       write( ", Needs ammo type: ", object.ammo_type );
  545.     endif;
  546.   elsif object.type = AMMO then
  547.     write( ", Ammo Type: ", object.ammotype );
  548.     if object.traptype then
  549.       write( ", Poisoned" );
  550.     endif;
  551.     if object.damage then
  552.       write( ", Extra Damage: ", object.damage );
  553.     endif;
  554.   elsif object.type = ARMOR or object.type = SHIELD then
  555.     write( ", Armor Class: ", object.ac );
  556.     if object.cursed then
  557.       write( " Cursed!" );
  558.     endif;
  559.   elsif object.type = AMULET or object.type = RING or object.type = GEMS then
  560.     if object.class then
  561.       write( ", Class: ", object.class );
  562.       write( ", Charges: ", object.charges );
  563.       if object.class <> CURE then
  564.         write( ", Units: ", object.units );
  565.         if object.permanent then
  566.           write( ", Permanent!" );
  567.         else
  568.           write( ", Temporary" );
  569.         endif;
  570.       endif;
  571.       if object.cursed then
  572.         write( ", Cursed!" );
  573.       endif;
  574.     endif;
  575.   elsif object.type = SCROLL then
  576.     write( ", Class: ", object.class );
  577.   elsif object.type = STAFF then
  578.     write( ", Class: ", object.class, ", Charges: ", object.charges );
  579.   elsif object.type = CHEST then
  580.     if object.locktype then
  581.       write( ", Locked!" );
  582.       if object.traptype = 0 then
  583.         write( ", no traps" );
  584.       elsif object.traptype = 1 then
  585.         write( ", poison trap" );
  586.       else
  587.         write( ", bomb damage: ", object.traptype );
  588.       endif;
  589.     endif;
  590. ! elsif object.type = KEYS     then
  591. !   nothing special about it
  592. ! elsif object.type = BOOK     then
  593. !   nothing special about it
  594. ! elsif object.type = GOLDSACK then
  595. !   nothing special about it
  596. ! elsif object.type = TORCH    then
  597. !   nothing special about it
  598. ! elsif object.type = LANTERN  then
  599. !   nothing special about it
  600. ! elsif object.type = ROPE     then
  601. !   nothing special about it
  602. ! elsif object.type = HOOKS    then
  603. !   nothing special about it
  604. ! elsif object.type = MIRROR   then
  605. !   nothing special about it
  606. ! elsif object.type = SIGN     then
  607. !   nothing special about it
  608.   elsif object.type = VEHICLE then
  609.     write( ", Class: ", object.class );
  610. ! else
  611. !   user defined type?
  612.   endif;
  613.   if object.weight > 1 and object.weight < 256 then
  614.     write( ", Weight: ", object.weight );
  615.   endif;
  616.   writeln( "." );
  617.   return;
  618.  
  619. !------------------------------------------------------------------------!
  620. !
  621. ! SUBROUTINE: M1_INVOKE
  622. !
  623. ! Type 1 Magic - Affects the person invoking the magic..
  624. !
  625. ! This portion of the script is invoked whenever an individual in the
  626. ! adventurer's group:
  627. !
  628. !  a) Eats food that has a magical effect
  629. !  b) Drinks a potion with a magical effect
  630. !  c) Successfully wears a ring or an amulet with a magical effect
  631. !  d) Uses a GEM that has a magical effect.
  632. !
  633. ! When invoked, PLAYER is the person that will be affected, and CURRITEM
  634. ! is the item that has the magical effect, and which is either being
  635. ! worn or in the character's backpack.  OBJECT and NPC are not defined.
  636. !
  637. !------------------------------------------------------------------------!
  638. :M1_INVOKE
  639. !------------------------------------------------------------------------!
  640.  
  641.   if curritem.cursed and curritem.permanent then
  642.     curritem.permanent = FALSE;
  643.     writeln( "WARNING: This object was 'cursed' and had 'permanent' effect!" );
  644.     writeln( "WARNING: The effect has been made 'temporary' by OBJECT.SCR" );
  645.   endif;
  646.  
  647.   on curritem.class goto
  648.     M1_NONE,    M1_CURE,    M1_HEAL,    M1_POISON,    M1_RESTORE,
  649.     M1_STR,     M1_DEX,     M1_SPD,     M1_AIM,       M1_AC,
  650.     M1_HP,      M1_IQ,      M1_PWR;
  651.  
  652. :M1_NONE
  653.   writeln( "Nothing happens.." );
  654.   return;
  655.  
  656. :M1_CURE
  657.   if player.poisoned then
  658.     player.poisoned = 0;
  659.     writeln( player.name, " is now cured." );
  660.   else
  661.     writeln( "Nothing happens.." );
  662.   endif;
  663.   return;
  664.  
  665. :M1_HEAL
  666.   if player.hp >= player.mhp then
  667.     writeln( "Nothing happens.." );
  668.   elsif player.hp = 0 then
  669.     writeln( player.name, " is beyond help.." );
  670.   else
  671.     if curritem.units > 0 then
  672.       L(0) = curritem.units;                   ! always heals the same points !
  673.     else
  674.       L(0) = random(player.mhp - player.hp)+1; ! heal a random number of points !
  675.     endif;
  676.     voice( "Tada", 1000 );
  677.     if player.hp + L(0) < player.mhp then
  678.       writeln( player.name, " heals ", L(0), " hit points.." );
  679.       inc( player.hp, L(0) );
  680.     else
  681.       writeln( player.name, " has been completely healed!" );
  682.       player.hp = player.mhp;
  683.     endif;
  684.   endif;
  685.   return;
  686.  
  687. :M1_POISON
  688.   if NOT player.poisoned then
  689.     player.poisoned = 1;
  690.     voice( "DudSpell", 1000 );
  691.     writeln( "You feel sick.." );
  692.   else
  693.     voice( "Boing", 1000 );
  694.     writeln( "You feel worse.." );
  695.   endif;
  696.   return;
  697.  
  698. :M1_RESTORE
  699.   if player.hp >= player.mhp then
  700.     writeln( "Nothing happens.." );
  701.   elsif player.hp = 0 then
  702.     writeln( player.name, " is beyond help.." );
  703.   else
  704.     voice( "OkSpell", 1000 );
  705.     player.hp = player.mhp;
  706.     writeln( player.name, " is completely healed!" );
  707.   endif;
  708.   return;
  709.  
  710. :M1_STR
  711.   if curritem.cursed then
  712.     player.str = 0;
  713.     voice( "DudSpell", 1000 );
  714.     writeln( "Something went wrong.." );
  715.   else
  716.     voice( "OkSpell", 1000 );
  717.     inc( player.str, curritem.units );
  718.     if curritem.permanent then
  719.       inc( player.mstr, curritem.units );
  720.     endif;
  721.     writeln( player.name, "'s strength increased by ", curritem.units, "!" );
  722.   endif;
  723.   return;
  724.  
  725. :M1_DEX
  726.   if curritem.cursed then
  727.     player.dex = 0;
  728.     voice( "DudSpell", 1000 );
  729.     writeln( "Something went wrong.." );
  730.   else
  731.     voice( "OkSpell", 1000 );
  732.     inc( player.dex, curritem.units );
  733.     if curritem.permanent then
  734.       inc( player.mdex, curritem.units );
  735.     endif;
  736.     writeln( player.name, "'s dexterity increased by ", curritem.units, "!" );
  737.   endif;
  738.   return;
  739.  
  740. :M1_SPD
  741.   if curritem.cursed then
  742.     player.spd = 0;
  743.     voice( "DudSpell", 1000 );
  744.     writeln( "Something went wrong.." );
  745.   else
  746.     voice( "OkSpell", 1000 );
  747.     inc( player.spd, curritem.units );
  748.     if curritem.permanent then
  749.       inc( player.mspd, curritem.units );
  750.     endif;
  751.     writeln( player.name, "'s speed increased by ", curritem.units, "!" );
  752.   endif;
  753.   return;
  754.  
  755. :M1_AIM
  756.   if curritem.cursed then
  757.     player.aim = 0;
  758.     voice( "DudSpell", 1000 );
  759.     writeln( "Something went wrong.." );
  760.   else
  761.     voice( "OkSpell", 1000 );
  762.     inc( player.aim, curritem.units );
  763.     if curritem.permanent then
  764.       inc( player.maim, curritem.units );
  765.     endif;
  766.     writeln( player.name, "'s aim increased by ", curritem.units, "!" );
  767.   endif;
  768.   return;
  769.  
  770. :M1_AC
  771.   if curritem.cursed then
  772.     player.ac = 0;
  773.     voice( "DudSpell", 1000 );
  774.     writeln( "Something went wrong.." );
  775.   else
  776.     voice( "OkSpell", 1000 );
  777.     inc( player.ac, curritem.units );
  778.     if curritem.permanent then
  779.       inc( player.mac, curritem.units );
  780.     endif;
  781.     writeln( player.name, "'s armor class increased by ", curritem.units, "!" );
  782.   endif;
  783.   return;
  784.  
  785. :M1_HP
  786.   if curritem.cursed then
  787.     player.hp = player.hp / 3 + 1;
  788.     writeln( player.name, " has been seriously injured!" );
  789.   else
  790.     voice( "OkSpell", 1000 );
  791.     inc( player.hp, curritem.units );
  792.     if curritem.permanent then
  793.       inc( player.mhp, curritem.units );
  794.     endif;
  795.     writeln( player.name, "'s hit points increased by ", curritem.units, "!" );
  796.   endif;
  797.   return;
  798.  
  799. :M1_IQ
  800.   if curritem.cursed then
  801.     player.iq = 0;
  802.     voice( "DudSpell", 1000 );
  803.     writeln( "Something went wrong.." );
  804.   else
  805.     voice( "OkSpell", 1000 );
  806.     inc( player.iq, curritem.units );
  807.     if curritem.permanent then
  808.       inc( player.miq, curritem.units );
  809.     endif;
  810.     writeln( player.name, "'s i.q. increased by ", curritem.units, "!" );
  811.   endif;
  812.   return;
  813.  
  814. :M1_PWR
  815.   if player.class = ELF or player.class = WIZARD then
  816.     if curritem.cursed then
  817.       player.pwr = 0;
  818.       voice( "DudSpell", 1000 );
  819.       writeln( "Something went wrong.." );
  820.     else
  821.       inc( player.pwr, curritem.units );
  822.       if curritem.permanent then
  823.         inc( player.mpwr, curritem.units );
  824.       endif;
  825.       voice( "OkSpell", 1000 );
  826.       writeln( player.name, "'s power increased by ", curritem.units, "!" );
  827.     endif;
  828.   else
  829.     voice( "Argh", 1000 );
  830.     write( player.name, " screams and falls to the ground, " );
  831.     if player.hp < 3 then
  832.       writeln( "dead!" );
  833.       player.hp = 0;
  834.     else
  835.       writeln( "holding his head.." );
  836.       dec( player.hp, 2 );
  837.     endif;
  838.   endif;
  839.   return;
  840.     
  841. !------------------------------------------------------------------------!
  842. !
  843. ! SUBROUTINE: M2_INVOKE
  844. !
  845. ! Type 2 Magic - Affects an object or a another person
  846. !
  847. ! This portion of the script handles magic spells which affect objects
  848. ! or persons other than the caster.  When invoked, the PLAYER is the
  849. ! person that invoked the spell and CURRITEM is the object that was used
  850. ! to invoke the spell (which is either being worn or carried by the
  851. ! player).
  852. !
  853. ! The OBJECT and NPC are undefined.  If the spell requires a target,
  854. ! the 'LOCATE' function can be used to select an object or character
  855. ! to cast the spell on.  The locate function returns the distance in blocks
  856. ! to the selected target.  If none is selected, the value is -1, and FAILURE
  857. ! is set.
  858. !
  859. ! After a LOCATE, either OBJECT or NPC will be set depending on whether the
  860. ! user selected an object or a character (or monster, during a fight).
  861. !
  862. ! To figure out which one was selected, check if NPC.COUNT is greater than
  863. ! 0.  If it is, a character was selected.  If it is not, then an object was
  864. ! selected.
  865. !
  866. !------------------------------------------------------------------------!
  867. :M2_INVOKE
  868. !------------------------------------------------------------------------!
  869.  
  870.   if curritem.class = NONE then
  871.     writeln( "Nothing happens.." );
  872.     return;
  873.   endif;
  874.  
  875.   if curritem.count = 0 then
  876.     writeln( "Oops, no object in OBJECT.SCR, m2 invoke" );
  877.     stop;
  878.   endif;
  879.  
  880.   if curritem.class = DAMAGE or curritem.class = CONFUSE or
  881.      curritem.class = SCARE  or curritem.class = PARALYZE or
  882.      curritem.class = KILL then
  883.     if not fighting then
  884.       writeln( "This spell can only be used during a fight.." );
  885.       return;
  886.     endif;
  887.     !
  888.     ! L(5) will contain the TOTAL experience points gained when done..
  889.     ! L(6) is the maximum damage that will be done to a single monster..
  890.     ! L(8) is the maximum total damage that can be done to a group of monsters..
  891.     ! L(9) is the TOTAL number of monsters affected AFTER the spell
  892.     !
  893.     L(5) = 0;
  894.     L(6) = player.level + adjustments(player.pwr) / 2 + 1;
  895.     if L(6) <= 0 then
  896.       writeln( "The spell failed.." );
  897.       STOP;
  898.     endif;
  899.     if curritem.units then
  900.       L(8) = curritem.units;
  901.     else
  902.       L(8) = player.iq + adjustments(player.iq);
  903.     endif;
  904.     L(9) = 0;
  905.   endif;
  906.  
  907.   if curritem.type = STAFF and curritem.charges = 0 then
  908.     writeln( "The ", curritem.name, " doesn't work.." );
  909.     return;
  910.   endif;
  911.      
  912.   if curritem.class <> LEAVE  and
  913.      curritem.class <> ZOOM   and
  914.      curritem.class <> INFORM and
  915.      curritem.class <> DOORS  and
  916.      curritem.class <> RESURRECT then
  917.     write( curritem.class, " what:" );
  918.     L(1) = locate;  ! SETS THE TARGET FOR THE SPELL ! 
  919.     if L(1) = 0 then
  920.       writeln( "nothing.." );
  921.       return;
  922.     endif;
  923.     ! Either NPC.COUNT or OBJECT.COUNT identifies selected object/char !
  924.     if npc.count then ! It's a character, not an object..
  925.       if npc.type = HOSTILE then
  926.         writeln( npc.name );  ! monster's don't have classes.. !
  927.       else
  928.         writeln( npc.class ); ! Human, elf, dwarf, etc..       !
  929.       endif;
  930.       if curritem.class = DESTROY  or curritem.class = DUPLICATE or
  931.          curritem.class = RECHARGE or curritem.class = FLOAT then
  932.         writeln( "This spell only work's on objects!" );
  933.         goto M2_EXIT;
  934.       endif;
  935.     else
  936.       writeln( object.type );  ! Food, weapon, ring, etc..      !
  937.     endif;
  938.   endif;
  939.  
  940.   on curritem.class goto 
  941.     M2_EXIT,     M2_DESTROY,  M2_DUPLICATE, M2_LEAVE,
  942.     M2_RESURRECT,M2_INFORM,   M2_LOCATE,    M2_KILL, 
  943.     M2_CONFUSE,  M2_SCARE,    M2_DAMAGE,    M2_PARALYZE,
  944.     M2_RECHARGE, M2_FLOAT,    M2_ANALYZE,   M2_ZOOM;
  945.  
  946. :M2_NONE      ! No magic..
  947.   writeln( "Nothing happens.." );
  948.   goto M2_EXIT;
  949.  
  950. :M2_DESTROY   ! Destroy an object                      pwr = 5, rng=10
  951.   ! if player.pwr < 5 goto M2_NOPOWER; ! No power check needed
  952.   if L(1) > 10 goto M2_OUTOFRANGE;
  953.   voice( "Explode", 1000 );
  954.   writeln( "The ", object.type, " is destroyed.." );
  955.   vanish( object );
  956.   L(4) = 5;
  957.   goto M2_EXIT;
  958.  
  959. :M2_DUPLICATE ! Duplicates an object                   pwr = 40, rng=1
  960.   ! if player.pwr < 40 goto M2_NOPOWER; ! No power check needed
  961.   if L(1) > 1 goto M2_OUTOFRANGE;
  962.   inc( object.count, 1 ); ! Creates an identical copy ! 
  963.   L(4) = 40;
  964.   goto M2_EXIT;
  965.  
  966. :M2_LEAVE     ! Exit through the 'exit' door from anywhere...  
  967.   if world.type <> DUNGEON then
  968.     voice( "Boing", 1000 );
  969.     writeln( "This spell only work's in dungeons.." );
  970.     return;
  971.   endif;
  972.   ! if player.pwr < 5 goto M2_NOPOWER; ! No power check needed
  973.   enter( world.edgedoor );
  974.   voice( "OkSpell", 1000 );
  975.   writeln( "You leave this level of the dungeon.." );
  976.   L(4) = 5;
  977.   goto M2_EXIT;
  978.  
  979. :M2_RESURRECT ! Revive a DEAD person                   pwr = 50, rng=1
  980.   ! if player.pwr < 50 goto M2_NOPOWER; ! No power check needed
  981.   if L(1) > 1 goto M2_OUTOFRANGE;
  982.   write( "Resurrect: " );
  983.   L(0) = select( group );
  984.   if player.hp > 0 then
  985.     voice( "Boing", 1000 );
  986.     writeln( "This player is NOT dead!" );
  987.     return;
  988.   endif;
  989.   voice( "OkSpell", 1000 );
  990.   writeln( player.name );
  991.   player.hp  = 2;
  992.   writeln( player.name, " is alive, but weak.." );
  993.   L(4) = 50;
  994.   goto M2_EXIT;
  995.   
  996. :M2_INFORM    ! Displays some text                     pwr =  5
  997.   ! if player.pwr < 5 goto M2_NOPOWER; ! No power check needed
  998.   if L(1) > 5 goto M2_OUTOFRANGE;
  999.   loadhint;
  1000.   writeln( "The wind seems to carry a random phrase to your ears.." );
  1001.   writeln( s0 );
  1002.   L(4) = 5;
  1003.   goto M2_EXIT;
  1004.  
  1005. :M2_LOCATE    ! Locate doors                           pwr = 10
  1006.   ! if player.pwr < 10 goto M2_NOPOWER; ! No power check needed
  1007.   if L(1) > 10 goto M2_OUTOFRANGE;
  1008.   L(0) = 0;
  1009.   :LDLOOP
  1010.     if world.doorx(L0) > 0 and world.doory(L0) > 0 then
  1011.       frame( world.doorx(L0), world.doory(L0), SYS_FRAME );
  1012.     endif;
  1013.     inc(L0);
  1014.   if L(0) < 16 goto LDLOOP;
  1015.   L(4) = 10;
  1016.   goto M2_EXIT;
  1017.  
  1018. :M2_KILL      ! Kill 1 enemy during battle             pwr = 20, rng=6
  1019.   writeln( npc.name, " killed. +", npc.hp, " exp." );
  1020.   inc( player.exp, npc.hp );
  1021.   npc.hp = 0;
  1022.   STOP;
  1023.  
  1024. :M2_DAMAGE    ! Causes damage to monsters              pwr =  5, rng=12
  1025.   S0 = "hit";
  1026.   foreach npc do
  1027.     L(7) = min( npc.hp, random(L6) );  ! How much damage to this one monster?
  1028.     if L(7) > 0 then
  1029.       frame(npc.x, npc.y, SYS_SPLAT); wait(1); frame(npc.x, npc.y, SYS_SPLAT);
  1030.       write( npc.name );
  1031.       if L(7) < npc.hp then
  1032.         write( " hit." );
  1033.         dec( npc.hp, L(7) );           ! Hit the monster..
  1034.       else
  1035.         write( " killed!" );
  1036.         npc.hp = 0;
  1037.       endif;
  1038.       writeln( " +", L(7), " exp." );
  1039.       inc(L9);                       ! Count of affected npcs
  1040.       inc( L(5), L(7) );                 ! Accumulate experience..
  1041.       if L(5) > L(8) goto DCSPEXIT;      ! Stop when total of L(8) points used
  1042.     endif;
  1043.   endfor;  
  1044.   goto DCSPEXIT;
  1045.  
  1046. :M2_CONFUSE   ! Makes monsters shoot at other monsters pwr =  1, rng=12
  1047.   S0 = "confused";
  1048.   foreach npc do
  1049.     L(7) = min( npc.hp, random(L6) );  ! How much confusion to this one monster?
  1050.     if L(7) > 0 and npc.confused = 0 then
  1051.       frame(npc.x, npc.y, SYS_SPLAT); wait(1); frame(npc.x, npc.y, SYS_SPLAT);
  1052.       inc(L9);                       ! Count of affected npcs
  1053.       npc.confused = L(7);             ! Confuse for 'n' units
  1054.       inc( L(5), L(7) );                 ! Accumulate experience..
  1055.       if L(5) > L(8) goto DCSPEXIT;      ! Stop when total of L(8) points used
  1056.     endif;
  1057.   endfor;  
  1058.   goto DCSPEXIT;
  1059.  
  1060. :M2_SCARE     ! Scares monsters                        pwr =  2, rng=12
  1061.   S0 = "scared";
  1062.   foreach npc do
  1063.     L(7) = min( npc.hp, random(L6) );  ! How much 'fright' to this one monster?
  1064.     if L(7) > 0 and npc.scared = 0 then
  1065.       frame(npc.x, npc.y, SYS_SPLAT); wait(1); frame(npc.x, npc.y, SYS_SPLAT);
  1066.       inc(L9);
  1067.       npc.scared = L(7);               ! Frighten for 'n' units
  1068.       inc( L(5), L(7) );                 ! Accumulate experience..
  1069.       if L(5) > L(8) goto DCSPEXIT;      ! Stop when total of L(8) points used
  1070.     endif;
  1071.   endfor;  
  1072.   goto DCSPEXIT;
  1073.  
  1074. :M2_PARALYZE  ! Monster can't move                     pwr =  5, rng=12
  1075.   S0 = "paralyzed";
  1076.   foreach npc do
  1077.     L(7) = min( npc.hp, random(L6) );  ! How much paralysis to this one monster?
  1078.     if L(7) > 0 and npc.paralyzed = 0 then
  1079.       frame(npc.x, npc.y, SYS_SPLAT); wait(1); frame(npc.x, npc.y, SYS_SPLAT);
  1080.       inc(L9);
  1081.       npc.paralyzed = L(7);            ! Paralyze for 'n' units
  1082.       inc( L(5), L(7) );                 ! Accumulate experience..
  1083.       if L(5) > L(8) goto DCSPEXIT;      ! Stop when total of L(8) points used
  1084.     endif;
  1085.   endfor;  
  1086.   goto DCSPEXIT;
  1087.  
  1088. :M2_RECHARGE  ! Recharge an ITEM                       pwr = 25, rng=1
  1089.   ! if player.pwr < 25 goto M2_NOPOWER; ! No power check needed
  1090.   if L(1) > 1 goto M2_OUTOFRANGE;
  1091.   if object.type = RING or object.type = AMULET or object.type = STAFF then
  1092.     inc( object.charges, random(player.level)+1 );
  1093.     voice( "OkSpell", 1000 );
  1094.     writeln( "The ", object.type, " now has ", object.charges, " charges." );
  1095.   else
  1096.     voice( "Boing", 1000 );
  1097.     writeln( "The smell of rotten eggs fills the air.." );
  1098.   endif;
  1099.   L(4) = 25;
  1100.   goto M2_EXIT;
  1101.  
  1102. :M2_FLOAT     ! Remove an object's weight              pwr = 10, rng=1
  1103.   ! if player.pwr < 10 goto M2_NOPOWER; ! No power check needed
  1104.   if L(1) > 1 goto M2_OUTOFRANGE;
  1105.   if object.weight < 255 then
  1106.     object.weight = object.weight / 2 + 1;
  1107.     voice( "OkSpell", 1000 );
  1108.     writeln( "The ", object.type, " is now much lighter.." );
  1109.   else
  1110.     voice( "Boing", 1000 );
  1111.     writeln( "It's didn't work.  The ", object.type, " is too heavy." );
  1112.   endif;
  1113.   L(4) = 10;
  1114.   goto M2_EXIT;
  1115.  
  1116. :M2_ANALYZE   ! Discover object's properties           pwr = 10, rng=1
  1117.   ! if player.pwr < 10 goto M2_NOPOWER; ! No power check needed
  1118.   if L(1) > 1  goto M2_OUTOFRANGE;
  1119.   L(255) = TRUE;   ! Give DETAILED description !
  1120.   gosub DESCRIBE;
  1121.   L(4) = 10;
  1122.   goto M2_EXIT;
  1123.  
  1124. :M2_ZOOM      ! View the world.. 
  1125.   ! if player.pwr < 25 goto M2_NOPOWER; ! No power check needed
  1126.   viewpcx( world );
  1127.   if success then
  1128.     pause;
  1129.   endif;
  1130.   paint( screen ); ! If you don't have any WORLD###.PCX files, you can use !
  1131.                    ! paint( WINDOW ) instead of paint( SCREEN) !
  1132.   L(4) = 25;
  1133.   goto M2_EXIT;
  1134.  
  1135. :M2_NOPOWER
  1136.   writeln( "You don't have enough power!" );
  1137.   return;
  1138.  
  1139. :M2_OUTOFRANGE
  1140.   writeln( "You are too far away from the ", object.name );
  1141.   return;
  1142.  
  1143. :DCSPEXIT
  1144.   if L(9) then
  1145.     write( L(9), " foes were ", S0 );
  1146.     if L(5) then  
  1147.       writeln( " for a total of +", L(5), " experience!" );
  1148.       inc( player.exp, L(5) );           ! Grant experience..
  1149.     else
  1150.       writeln( " With no effect" );
  1151.     endif;
  1152.   else
  1153.     writeln( "No effect.." );
  1154.   endif;
  1155.   goto M2_EXIT;
  1156.  
  1157. :M2_EXIT
  1158.   if curritem.count > 0 then
  1159.     if curritem.count > 1 then
  1160.       curritem.name = curritem.class;
  1161.     endif;
  1162.     if curritem.type = SCROLL then
  1163.       dec( curritem.count ); ! Item disapears if count reaches 0 !
  1164.     elsif curritem.type = STAFF then
  1165.       dec( curritem.charges ); ! One less !
  1166.     endif;
  1167.   else
  1168.     dec( player.pwr, L(4) );   ! A spell !
  1169.   endif;
  1170.   return;
  1171.  
  1172.  
  1173.  
  1174.